{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import agentpy as ap\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import IPython\n",
    "# 解决绘图中的中文乱码问题\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei'] \n",
    "plt.rcParams['axes.unicode_minus'] = False \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(AgentSet (9 objects), 0)\n",
      "[22, 94, 139, 16, 1, 40, 99, 67, 37]\n",
      "Completed: 1 steps\n",
      "Run time: 0:00:00.001995\n",
      "Simulation finished\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "DataDict {\n",
       "'info': Dictionary with 9 keys\n",
       "'parameters': \n",
       "    'constants': Dictionary with 3 keys\n",
       "'reporters': DataFrame with 1 variable and 1 row\n",
       "}"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Evacuation(ap.Model):\n",
    "\n",
    "    def setup(self):\n",
    "        self.p = {\n",
    "            'size': 5,\n",
    "            'pop': 150,\n",
    "            'steps': 1,\n",
    "        }\n",
    "        # 创建agent\n",
    "        people = self.agents = ap.AgentDList(self, self.p['pop'])\n",
    "        self.mall = ap.Grid(self, [self.p['size']] * 2,\n",
    "                              track_empty=True,\n",
    "                              check_border=True)\n",
    "        # 对于每个网格，我们都可以添加一个字段，来表示这个网格的状态\n",
    "        # 这里设置为0表示这个网格是空闲的\n",
    "        self.mall.add_field('status',0)\n",
    "\n",
    "        # 设置墙的位置\n",
    "        self.mall['status'][:,0] = 1\n",
    "        self.mall['status'][:,-1] = 1\n",
    "        self.mall['status'][0,:] = 1\n",
    "        self.mall['status'][-1,:] = 1\n",
    "        # 设置门的位置\n",
    "        self.gate_1 = 20\n",
    "        self.gate_2 = 30\n",
    "        self.mall['status'][0,20:30] = 2\n",
    "\n",
    "        # 设置两个障碍的位置\n",
    "        # self.mall['status'][10,10:20] = 1\n",
    "        # self.mall['status'][10,30:40] = 1\n",
    "\n",
    "        # 设置一个遮挡门的障碍位置\n",
    "        # self.mall['status'][3,20:30] = 1\n",
    "\n",
    "        # 设置一个遮挡门的障碍位置，中间开一个小口\n",
    "        self.mall['status'][3,20:24] = 1\n",
    "        self.mall['status'][3,26:30] = 1\n",
    "\n",
    "        self.mall.add_agents(people, random=True)\n",
    "        # pos = set()\n",
    "        # while len(pos) < len(self.agents):\n",
    "        #     x = self.random.randint(1, self.p['size']-1)\n",
    "        #     y = self.random.randint(1, self.p['size']-1)\n",
    "        #     if  (x,y) not in pos and self.mall['status'][x][y]==0:\n",
    "        #         pos.add((x,y))\n",
    "\n",
    "        # self.mall.add_agents(people, positions=pos, empty=True)\n",
    "        # 设置每个agent上一步的选择，默认为0，即向前移动，-1表示向左移动，1表示向右移动\n",
    "        # 这个步骤主要防止agent在移动的过程中，出现左右横跳的情况\n",
    "        self.agents.Previous = 0\n",
    "        self.agents.condition = 1\n",
    "    \n",
    "    def step(self):        \n",
    "       \n",
    "        pops = self.agents.select(self.agents.condition == 1)\n",
    "        \n",
    "        for person in pops:\n",
    "            # 查询当前的agent的位置\n",
    "            pos = self.mall.positions[person]\n",
    "            grid_obj = self.mall.grid[pos[0]][pos[1]]\n",
    "            print(grid_obj)\n",
    "            print(grid_obj[0].id)\n",
    "            break\n",
    "        self.stop()\n",
    "\n",
    "        #     # 如果前方是墙\n",
    "        #     if mall_status[pos[0]-1][pos[1]] == 1:\n",
    "        #         # 如果已经走到顶\n",
    "        #         if pos[0]-1 ==0:\n",
    "        #             # 只会往门的方向移动\n",
    "        #             if pos[1] < self.gate_1:\n",
    "        #                 self.mall.move_to(person, (pos[0],pos[1]+1))\n",
    "        #             elif pos[1] >= self.gate_2:\n",
    "        #                 self.mall.move_to(person, (pos[0],pos[1]-1))\n",
    "        #         # 如果不是顶，则表示前面可能是障碍物\n",
    "        #         # 则随机选择左右的一个方向\n",
    "        #         else:\n",
    "        #             if person.Previous == 0:\n",
    "        #                 person.Previous = self.random.choice([-1, 1])\n",
    "        #             if mall_status[pos[0]][pos[1]+ person.Previous] == 0:\n",
    "        #                 self.mall.move_to(person, (pos[0],pos[1]+ person.Previous))\n",
    "                    \n",
    "        #     # 如果前面是门，则表示已经到达终点，agent可以离开\n",
    "        #     elif  mall_status[pos[0]-1][pos[1]] == 2:\n",
    "        #         self.agents.remove(person)\n",
    "        #         self.mall.remove_agents(person)\n",
    "\n",
    "        #     # 如果前方是空位\n",
    "        #     else:\n",
    "        #         # 判断指定的位置上是否有agent\n",
    "        #         # 如果没有agent，则将agent移动到指定的位置\n",
    "        #         if len(self.mall.grid[pos[0]-1][pos[1]][0].id) == 0:\n",
    "        #             # 在门的范围内，只会向上移动\n",
    "        #             if pos[1] > self.gate_1 and pos[1] <= self.gate_2-1:\n",
    "        #                 self.mall.move_to(person, (pos[0]-1,pos[1]))\n",
    "        #                 person.Previous = 0\n",
    "        #             else:\n",
    "        #                 choice = self.random.randint(0,10)\n",
    "        #             #70%的概率向上移动，30%的概率选择左右对齐门方向移动\n",
    "        #                 if choice < 7:\n",
    "        #                     self.mall.move_to(person, (pos[0]-1,pos[1]))\n",
    "        #                     person.Previous = 0\n",
    "        #                 else:\n",
    "        #                     if pos[1] <= self.gate_1:\n",
    "        #                         # 判断一下，不能上墙\n",
    "        #                         if mall_status[pos[0]][pos[1]+1] == 0:\n",
    "        #                             self.mall.move_to(person, (pos[0],pos[1]+1))\n",
    "        #                     elif pos[1] >= self.gate_2:\n",
    "        #                         if mall_status[pos[0]][pos[1]-1] == 0:\n",
    "        #                             self.mall.move_to(person, (pos[0],pos[1]-1))\n",
    "        #         else:\n",
    "        #             chioce = self.random.choice([-1, 1])\n",
    "        #             if mall_status[pos[0]][pos[1]+ chioce] == 0:\n",
    "        #                 self.mall.move_to(person, (pos[0],pos[1]+ chioce))\n",
    "                    \n",
    "        # if len(self.agents) <=0:\n",
    "        #     self.stop()\n",
    "    \n",
    "    def end(self):\n",
    "        pass\n",
    "        # for cell in self.agents:\n",
    "        #     print(cell.condition, end=' ')\n",
    "model = Evacuation()\n",
    "model.run()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py312",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
